﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ObjectTransposeApi.Helper
{
    /// <summary/>
    internal static class ReflectionHelper
    {
        /// <summary/>
        internal static PropertyInfo FetchMatchingProperty(
            PropertyInfo[] propertyInfos,
            string name,
            IEnumerable<PropertyMapper> propertyMappers)
        {
            // find a matching source property
            PropertyInfo propertyInfo = Array.Find(
                propertyInfos,
                value => value.Name == name);

            // if a matching source property is not found then move on
            if (propertyInfo != null)
            {
                return propertyInfo;
            }

            // if no proeprty mappers then exit
            if (propertyMappers == null)
            {
                return null;
            }

            foreach (PropertyMapper propertyMapper in propertyMappers)
            {
                // does the source name match
                if (propertyMapper.DestinationName != name)
                {
                    continue;
                }

                // find a matching source property
                PropertyInfo mapperSourcePropertyInfo = Array.Find(
                    propertyInfos,
                    value => value.Name == propertyMapper.SourceName);

                // if a matching source property is not found then move on
                if (mapperSourcePropertyInfo != null)
                {
                    return mapperSourcePropertyInfo;
                }
            }

            // no match ws found
            return null;
        }

        /// <summary/>
        internal static object FetchPropertyValue(
            PropertyInfo propertyInfo,
            object value)
        {
            // if null then exit
            if (value == null)
            {
                return null;
            }

            // return the value
            return propertyInfo.GetValue(value, null);
        }

        /// <summary/>
        internal static PropertyInfo FetchGetProperty(
            Type type,
            string name)
        {
            return type.GetProperty(
                name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
        }

        /// <summary/>
        internal static PropertyInfo[] FetchGetSetProperties(Type type)
        {
            return type.GetProperties(
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty);
        }

        /// <summary/>
        internal static PropertyInfo[] FetchGetProperties(Type type)
        {
            return type.GetProperties(
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
        }

        /// <summary/>
        internal static ConstructorInfo FetchConstructor(
            Type type, 
            Type[] parameterTypes)
        {
            // this only returns public methods
            return type.GetConstructor(parameterTypes);
        }
    }
}
